/**********************************************************
 * ANT_Utils.c - contains the code for the header file
 * ANT_Utils.h
 *
 * By: Team 4
 * *******************************************************/

#include "msp430bt5190.h"
#include "./Includes/display.h"
#include <stdio.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Semaphore.h>
#include "./Includes/GSGCdef.h"
#include "./Includes/Message.h"

// Global Functions
extern const Semaphore_Handle ANTMesgSem;
extern const Semaphore_Handle NewANTMesgSem;

/**********************************************************
 * Helper Functions - functions called for convenience by
 * the later functions in the code
 *******************************************************/

//Delay Function
void delay(unsigned int time){
  volatile unsigned int i;
  for(i = 0; i < time; i++);
}

//Returns the xor of all previous bit
char checksum(char * message, int num){
  int i;
  char result = message[0];
  
  for(i = 1; i < num; i++){
    result ^= message[i];
  }

  return result;
}


// Sets-up UART communications for the ANT module
// UART requirements
// Baud Rate = 4800
// Data length 8 bits
// Stop-bit 1
// Parity None

int UART_ANT_init(){
  // Setting up the UART Communications
  //Setting UCSWRST
  UCA3CTL1 |= UCSWRST; //Start reconfiguring by setting UCSWRST bit
  
  //Initializing Registers
  //UCA2CTL0 &= ~UCMSB; //selects LSB first
  //UCA2CTL0 &= ~UC7BIT; //Set to 8 bit mode
  //UCA2CTL0 &= ~UCPEN;  //Set no parity bit
  UCA3CTL0 = 0; //No parity, LSB first and one stop bit

  //Set up Baud Rate
  UCA3CTL1 = UCSSEL1; // UCLK = ACLK = 8.067226 MHz
  UCA3BR0 = 0xB3; // ACLK/4800 = 70 = 0x690
  UCA3BR1 = 0x06; // BR0(low byte) BR1(high byte)
  UCA3MCTL = 0x5<<1; // set second modulation stage
                    //the remander of ACLK/Baud rate 0
  UCA3MCTL &= ~UCOS16; // disable over sampling

  //UCA0CTL1 |= UCRXEIE; // Enable UART0 RX/TX interrupt
  //UCA0IFG &= ~UCRXIFG; // set the RX flag low
  //UCA0IFG &= ~UCTXIFG; // set the TX flag low
  
  // Configuring Ports
  P10SEL |= 0x30; // P9.4,5 = UART0 TXD/RXD
  P10DIR &= ~0x20; // P9.5 (RX) is an input
  P10DIR |= 0x10; // P9.4 (TX) is an output
  
  //Clearing UCSWRST
  UCA3CTL1 &= ~UCSWRST; //Initialize USART state machine
  
  //Setting Interrupts
  UCA3IE |= UCRXIE;
  
  return 0;
}

//This function setsup TA0.1 (P1.2) as the slow clock for 
//the ANT+ module with frequency of 32.768kHz which 
//requires dividing the SMCLK(1.048756MHz) by 32
int setup_ANT_Slow_Clock(){

  //Set source seleckt to SMCLK or bits 9-8 to 10
  //input devider to 1 or bits 7-6 to 00
  //Set mode to up bits 5-4 to 01
  //And no interupts bits 1-0 to 00
  TA0CTL = 0x210;

  TA0CCTL1 = 0x40; //set bit 7-5 to 010 for Toggle/reset mode 
  TA0CCR1 = 125; //signal goes high 16 ticks into cycle
  TA0CCR0 = 249; //signal goes low and counter resets @ 32 ticks

  TA0CTL |= TACLR; //reset the timer

  //Configure Port for P1.2
  P1SEL |= 0x4;
  P1DIR |= 0x4;

  return 0;
}

// This function sets up all the hardware related parts for
// the ANT+ code 

int setup_ANT_hardware(){
  
  //basic delay function one cycle ~ 1.22 usec
  //wait for 500ms after startup before reseting
  volatile unsigned int i,j;

  //Setup RTS(8.1) as input and CTS(1.4) as output
  P8DIR &= ~0x2; //set pin 8.1 as input(0)
  P8SEL &= ~0x2;

  P1DIR |= 0x10;  //set pin 1.4 as output(1)
  P1SEL &= ~0x10;
  P1OUT &= ~0x10; //set pin 1.4 low for reset (no IO allowed)

  //Settup the UART interface
  //Do before so that the UART is pulled high
  UART_ANT_init();

  //Setup nSHUTD(8.2) active low shutdown
  P8DIR |= 0x4; //set pin 8.2 as output(1)
  P8SEL &= ~0x4;
  P8OUT &= ~0x4; //set nSHUTD(8.2) low to reset system

  //basic delay function one cycle ~ 1.22 usec
  //needs minimum of 5ms of low to rest clock
  for(j=0; j < 10; j++)
    delay(45000);

  //Setup the slow clock
  setup_ANT_Slow_Clock();

  P8OUT |= 0x4; //set nSHUTD(8.2) high to finish reset
  P1OUT |= 0x10; //set CTS(1.4) high so no messages are sent

  //wait till RTS(8.1) is low signaling the chip is ready
  while(P8IN & 0x2);

  return 0;
}

/**********************************************************
 * Transmission Functions - These functions control the
 * transmission between the MSP430 and PAN 1315
 *******************************************************/

// transmit_ANT -  takes the data given in the data array
// and transmits the first num of them to the PAN 1315
int transmit_ANT(char * data, int num){
  int i;

  //Send the ANT+ Command
  for(i = 0; i < num; i++){
    // currently use empty while loop to create wait
    // should switch to an interupt in the future
    while(!(UCA3IFG & UCTXIFG));  //Wait till buffer is ready

    // Check that HCI_RTS (pin 8.1) is low and is safe to send
    // It is high, not ready, so wait till it is
    //while(P8IN & 0x2); // In future switch to interrupts
    
    // It is low so send the data
    UCA3TXBUF = data[i];   //Send next command
  }

  return 0;
}

// read_ANT - reads in the latest string of bytes from the
// ANT+ module and places the values into the given array
// returns 0 if good
// returns 1 if checksum doesn't match
int read_ANT(char * data,int length){
  int i;

  Semaphore_pend(NewANTMesgSem, BIOS_WAIT_FOREVER); //Wait till a new message arrives

  // User the semaphore to provide mutual exclusion
  Semaphore_pend(ANTMesgSem, BIOS_WAIT_FOREVER);
      //the length of ANT message is four plus the length value
  	  //for Sync, Mesg Length, Mesg ID & Checksum bytes
  	  for(i = 0; i < (length + 4); i++)
  		  data[i] = ANTReadMessage[i];
  Semaphore_post(ANTMesgSem); //End of Mutex

  if(data[1] != length)
	  return -1; //Lengths don't match
  else
	  return 0; //Lengths match
  
}
